import { Component, OnInit, Input, Output, SimpleChanges, ViewChild, ElementRef } from '@angular/core';
import { List } from 'linqts';
//报警级别、类别数据模型
import { FaultLevel } from "../../../../entity/fault-level.model";
import { TurbComponent } from "../../../../entity/turbcomponent.model";
import { FaultData } from "../../../../entity/fault-data";
import { AlarmCategory } from "../../../../entity/alarm-category.model";
import { ITdDataTableColumn, TdDataTableComponent, IPageChangeEvent, TdDataTableService, TdDialogService, ITdDataTableSortChangeEvent, TdDataTableSortingOrder } from "@covalent/core";

import { FaultLevelService } from "../../../../service/fault_level.service";
import { AlarmCategoryService } from "../../../../service/alarm-category.service";
import { TurbcomponentService } from "../../../../service/turbcomponent.service";
import { AlarmListComponent } from "../../../alarm/alarm-search/alarm-list/alarm-list.component";
import { ApplicationService } from "../../../../service/application.service";
import { InterceptorService } from '../../../../service/interceptor/interceptor-service';

//列表数据模型
import { AlarmSearchData, FaultCount, FaultTableData } from "../../../alarm/alarm-search/alarm-search.data"
import { DataSourceService } from "../../../../service/data-source/data-source.service";
import { Http } from "@angular/http";
import { DatePipe } from "@angular/common";
import { NzMessageService } from 'ng-zorro-antd';

@Component({
  selector: 'app-alarm-list',
  templateUrl: './alarm-list.component.html',
  styleUrls: ['./alarm-list.component.css']
})
export class AlarmListDetailComponent implements OnInit {
  /**
   * 数据源服务
   * 
   * @private
   * @type {DataSourceService}
   * @memberof TurbineListComponent
   */
  private dataSource: DataSourceService;
  /**
	* 报警类别数据集合
	* 
	* @type @memberof AlarmListComponent
	*/
  public alarmCategoryDatas: AlarmSearchData[] = [];

	/**
	* 故障等级数据集合
	* 
	* @type @memberof AlarmListComponent
	*/
  public faultLevels: FaultLevel[] = [];

  public active: number = 0;
  private h = 1000 * 3600;

  /**
	* 故障统计数据集合
	* @type @memberof AlarmListComponent
	*/
  public faultCountData: FaultCount[] = [];
  public faultCountList: FaultCount[] = [];
  public pages: number;

  //故障类别数据集合
  public turbComponents: TurbComponent[] = [];

  //列表数据集合
  private faultDatas: FaultData[] = [];
  faultData1: FaultTableData[] = [];
  faultData2: FaultTableData[] = [];
  row: number = 0;
  @ViewChild("alarmTable")
  alarmTable: ElementRef;

  @ViewChild('countTable')
  countTable: ElementRef;
  rowC: number;

  // 统计数据
  faultData3: FaultCount[] = [];
  faultData4: FaultCount[] = [];
  sortO: number = -1;
  sortF: string = 'faultCount';
  sortFO: number = -1;
  sortFault: string = 'faultCode';
  /**
	 * 表头
	 * 
	 * @type {number}@memberof AlarmListComponent
	 */
  public columns: ITdDataTableColumn[] = [
    { name: 'faultCode', label: '故障码' },
    { name: 'turbComponentName', label: '故障类别', },
    { name: 'faultLevelName', label: '故障等级' },
    { name: 'faultDesc', label: '故障内容' },
    { name: 'faultTime', label: '时间' },
  ];
  cars: AlarmSearchData;
  constructor(
    private http: InterceptorService,
    private datePipe: DatePipe,
    private _dialogService: TdDialogService,
    private alarmCategoryService: AlarmCategoryService,
    private faultLevelService: FaultLevelService,
    private turbcomponentService: TurbcomponentService,
    private _message: NzMessageService,
    private application: ApplicationService,
  ) { }

  ngOnInit() {
    Promise.all([
      this.alarmCategoryService.getAlarmCategorys(),
      this.faultLevelService.getFaultLevelsWithSound(),      
      this.turbcomponentService.getTurbComponents()])
      .then(res => {
        if (res[1]) {
          this.faultLevels.push(...res[1]);
        }
        if (res[2]) {
          this.turbComponents.push(...res[2]);
        }
        this.initData(res[0]);
      })
      .catch(error => {
        if(this.application.appConfigData.isShowErr){
          this._message.info('报警数据初始化失败，' + error,{nzDuration: 3000});
        }
        
        //console.log("app-alarm-lamp has error", error);
      });
  }
  ngOnDestroy(): void {
    if (this.dataSource != null)
      this.dataSource.dispose();
  }

  initData(categorys: AlarmCategory[]) {
    if (!categorys) { return false; };
    categorys.forEach((category, index) => {

      let alarmCategoryData = {
        alarmCategoryId: category.alarmCategoryId,
        alarmCategoryName: category.alarmCategoryName,
        faultDatas: [],
        faultTableData: [],
        faultCounts: [],
        faultCountData:[],
        isChecked: index === 0 ? true : false,
        faultLevelTotals: this.faultLevels,
        turbComponentTotals: this.turbComponents,
        faultLength: 0
      };

      this.alarmCategoryDatas.push(alarmCategoryData);
    });
  }
  public onAlarmCategoryClick(alarmCategpry: AlarmSearchData) {
    alarmCategpry.isChecked = true;
    let alarmCategprys = this.alarmCategoryDatas.filter(o => o.alarmCategoryId != alarmCategpry.alarmCategoryId);
    if (alarmCategprys && alarmCategprys.length > 0) {
      alarmCategprys.map(o => o.isChecked = false);
    }
  }
  datasource: AlarmSearchData[];



  totalRecords: number;
  loadData(event: any, index: number) {
    setTimeout(() => {
      if (index) {
        this.alarmCategoryDatas[index].faultTableData = this.faultData2.slice(event.first, (event.first + event.rows))
      } else {
        this.alarmCategoryDatas[index].faultTableData = this.faultData1.slice(event.first, (event.first + event.rows))
      }

    }, 250);

  }
  upData(turbineIds: number[], startTime: Date, endTime: Date) {
    let faultDatas = [];
    this.alarmCategoryDatas.forEach(o => o.faultDatas = []);
    this.alarmCategoryDatas.forEach(o => o.faultCounts = []);
    this.alarmCategoryDatas.forEach(o => o.faultTableData = []);
    if (this.dataSource != null) {
      this.dataSource.dispose();
    }
    this.dataSource = new DataSourceService(this.http, this.datePipe);

    this.dataSource
      .history
      .getTurbineFaults(turbineIds, startTime, endTime)
      .then(res => {
        res.sort(function (a, b) {
          return new Date(b.faultTime).getTime() - new Date(a.faultTime).getTime();
        });

        this.faultDatas = [...res];
        faultDatas.push(...res);
        this.alarmCategoryDatas.forEach((category, i) => {
          // 表格统计数据集合
          const faultsLists: FaultTableData[] = [];
          category.faultDatas = [];
          category.faultCounts = [];
          category.faultTableData = [];
          let faultData: FaultData[] = [...faultDatas.filter(o => o.alarmCategoryId === category.alarmCategoryId)];
          faultData.forEach( fault => {
            const faultList = {
              factoryName:fault.factoryName,
              modelName:fault.modelName,
              farmName:fault.farmName,
              deviceName:fault.deviceName,
              faultCode: fault.faultCode,
              desc: fault.faultDesc,
              faultLevelName: fault.faultLevelName,
              components: fault.turbComponentName + '-' + fault.subcomponentName + '-' + fault.partsName,
              faultLevelColor: fault.faultLevelColor,
              faultTime: fault.faultTime,
              faultEndTime: fault.faultEndTime,
              faultContinueTime:Math.floor((new Date(fault.faultEndTime).getTime()-new Date(fault.faultTime).getTime())/1000/60/60),
              faultLevelId: fault.faultLevelId,
              turbComponentId: fault.turbComponentId,
              turbComponent: fault.turbComponentName,
              subcomponentName:fault.subcomponentName,
              partsName:fault.partsName,
              faultDesc:fault.faultDesc,
            };
            faultsLists.push(faultList);
          });
          const faultsAllCount = [...faultData];
          category.faultLength = faultsLists.length;
          if (i) {
            this.faultData2 = [...faultsLists];
          } else {
            this.faultData1 = [...faultsLists];
          }
          let faults: FaultTableData[] = faultsLists.slice(0, 10);
          /* let faults:FaultData[]=[];
          faults=[{
            turbineId:1,
            turbineName:"11",
            farmId:21,
            farmName:"1111",
            turbComponentId:1,
            turbComponentName:"",
            faultCode:"21",
            faultDesc:"ddddddds三生洒洒水所所sewee",
            faultLevelId:1,
            faultLevelName:"高",
            faultLevelColor:"#0ff",
            faultTime:new Date(),
            alarmCategoryId:1,
            alarmCategoryName:"ss",
            confirm:true
          };
          faults.push(obj) 
          faults.push(obj)  */

          category.faultTableData = [...faults];
          if (category.faultDatas) {
            let list = new List(category.faultDatas);
            this.faultLevels.forEach(level => {
              level.isChecked = true;
              level.faultLevelCount = list.Count(o => o.faultLevelId == level.faultLevelId);
            });

            this.turbComponents.forEach(turbComponent => {
              turbComponent.isChecked = true;
              turbComponent.turbComponentCount = list.Count(o => o.turbComponentId == turbComponent.turbComponentId)
            })
          }

          // 按code统计报警数量
          const counts: FaultCount[] = [];
          let faultCountsData: FaultCount[] = [];
          const list = new List(faultsAllCount);
          // 按code分组
          const groups = list.GroupBy(grouper => grouper.faultCode, mapper => mapper);
          const codes = Object.getOwnPropertyNames(groups);
          codes.forEach(code => {
            const codeList = new List<FaultData>(Object.getOwnPropertyDescriptor(groups, code).value);
            const codeListArr = new List<FaultData>(Object.getOwnPropertyDescriptor(groups, code).value).ToArray();
            const timeWork = codeList.Sum(o => new Date(o.faultEndTime).getTime() - new Date(o.faultTime).getTime());
            const faultCountData: FaultCount = {
              faultCode: code,
              farmName: codeListArr[0].farmName,
              deviceName: codeListArr[0].deviceName,
              faultDesc: codeListArr[0].faultDesc,
              faultLevelColor: codeListArr[0].faultLevelColor,
              faultWorkTime: Number((timeWork / this.h).toFixed(2)),
              faultCount: codeList.Count()
            };
            counts.push(faultCountData);
          });
          faultCountsData = [...counts]
          category.faultCountLength = faultCountsData.length;
          if (i) {
            this.faultData3 = [...faultCountsData];
          } else {
            this.faultData4 = [...faultCountsData];
          }
          const faultsC: FaultCount[] = faultCountsData.slice(0, 10);
          category.faultCounts = [...faultsC];
        });
        // this.row = Math.floor((this.alarmTable.nativeElement.clientHeight - 40) / 30);
        this.onResize();
      })
      .catch(error => {
        if(this.application.appConfigData.isShowErr) {
          this._message.info('历史报警数据' + error, {nzDuration: 3000});
        }
        
        //console.log("app-alarm-search has error", error);
      });
  }
  loadCountData(event: any, index: number) {
    setTimeout(() => {

      if (index) {
        this.alarmCategoryDatas[index].faultCounts = this.faultData3.slice(event.first, (event.first + event.rows));
      } else {
        this.alarmCategoryDatas[index].faultCounts = this.faultData4.slice(event.first, (event.first + event.rows));
      };

    }, 250);
  }
  onClickHeader(n: number) {
    this.active = n;
  }
  onResize() {
    if (this.active === 0) {
      this.row = Math.floor((this.alarmTable.nativeElement.clientHeight - 40) / 30);
      this.rowC = Math.floor((this.alarmTable.nativeElement.clientHeight - 40) / 30);
    } else {
      this.row = Math.floor((this.countTable.nativeElement.clientHeight - 40) / 30);
      this.rowC = Math.floor((this.countTable.nativeElement.clientHeight - 40) / 30);
    }
  }

  changeSort(ev) {
    if (!ev.order) {
      this.sortF = 'faultCount';
    } else {
      this.sortF = ev.field;
    }
  }

  changeFaultSort(ev) {
    if (!ev.order) {
      this.sortFault = 'faultCode';
    } else {
      this.sortFault = ev.field;
    }
  }
}


// WEBPACK FOOTER //
// ./src/app/module/monitor/turbine-detail/alarm-list/alarm-list.component.ts